package br.edu.unifei.cct720.alieninvasion.main.gui;

import java.awt.Dimension;
import java.io.IOException;
import java.util.List;

import javax.swing.ButtonGroup;

import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemAbout;
import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemAdvanced;
import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemBeginner;
import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemHighScore;
import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemIntermediate;
import br.edu.unifei.cct720.alieninvasion.components.gui.JMenuItemVolume;
import br.edu.unifei.cct720.alieninvasion.events.MyActionListener;
import br.edu.unifei.cct720.alieninvasion.resources.SoundEffect;
import br.edu.unifei.cct720.alieninvasion.resources.SoundEffect.Volume;
import br.edu.unifei.cct720.alieninvasion.utils.Constants;
import br.edu.unifei.cct720.alieninvasion.utils.HighestScoreFile;
import br.edu.unifei.cct720.alieninvasion.utils.Messages;

/**
 * Class that represents application GUI
 * 
 * @author Felipe Knappe
 *
 */
public class Game extends javax.swing.JFrame {

	/**
	 * Class Constructor
	 * 
	 * Create a new instance of Game frame with
	 * specified title
	 * 
	 * @param title The window title
	 * 
	 */
	public Game(String title) {
		super(title);
		this.initComponents();
		this.setUpBeginnerOptions();
		this.canvas.loadSoundSamples();	
	}

	/**
	 * Method responsible for initialize and disposal
	 * GUI components on the main view.
	 * 
	 */
	public void initComponents() {

		java.awt.GridBagConstraints gridBagConstraints;

		// Frame configuration values
		this.setVisible(true);
		this.setResizable(false);
		this.setLocation(225, 75);
		this.setSize(new Dimension(800, 625));

		// Components initialing
		canvas = new GameCanvas();
		menuBar = new javax.swing.JMenuBar();
		menuOptions = new javax.swing.JMenu("Options");
		menuGameLevels = new javax.swing.JMenu("Levels");
		menuAbout = new javax.swing.JMenu("Help");
		menuItemBeginner = new JMenuItemBeginner("Beginner", this);
		menuItemIntermediate = new JMenuItemIntermediate("Intermediate", this);
		menuItemAdvanced = new JMenuItemAdvanced("Advanced", this);
		menuItemVolume = new JMenuItemVolume("Mute sounds", this);
		menuItemHighScore = new JMenuItemHighScore("Hightest Scores...", this);
		menuItemAbout = new JMenuItemAbout("About...", this);

		this.setLayout(new java.awt.GridBagLayout());

		// Components disposal
		ButtonGroup bg = new ButtonGroup();
		bg.add(menuItemBeginner);
		bg.add(menuItemIntermediate);
		bg.add(menuItemAdvanced);

		MyActionListener myListener = new MyActionListener();

		menuItemBeginner.addActionListener(myListener);
		menuItemIntermediate.addActionListener(myListener);
		menuItemAdvanced.addActionListener(myListener);

		menuGameLevels.add(menuItemBeginner);
		menuGameLevels.add(menuItemIntermediate);
		menuGameLevels.add(menuItemAdvanced);
		menuBar.add(menuGameLevels);

		menuItemVolume.addActionListener(myListener);
		menuItemHighScore.addActionListener(myListener);
		menuOptions.add(menuItemVolume);
		menuOptions.add(menuItemHighScore);
		menuBar.add(menuOptions);

		menuItemAbout.addActionListener(myListener);
		menuAbout.add(menuItemAbout);
		menuBar.add(menuAbout);

		this.menuBar.setBounds(0, 0, 800, 50);
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.CENTER;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.weightx = 100.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		this.getContentPane().add(menuBar, gridBagConstraints);

		this.canvas.setBounds(0,50,800,600);
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.CENTER;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 100.0;
		gridBagConstraints.weighty = 100.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		this.getContentPane().add(this.canvas, gridBagConstraints);

		this.canvas.createBufferStrategy(2);
		this.canvas.setStrategy(this.canvas.getBufferStrategy());
		this.canvas.requestFocus();

		pack();
	}

	// Declaring GUI components

	/** The canvas for game execution */
	private GameCanvas canvas;

	/** The menu bar for game options */
	private javax.swing.JMenuBar menuBar;

	/** The menus for user */
	private javax.swing.JMenu menuOptions, menuGameLevels, menuAbout;

	/** The menu item for sound effects volume control */
	private JMenuItemVolume menuItemVolume;

	/** The menu item to set up beginner difficulty level */
	private JMenuItemBeginner menuItemBeginner;

	/** The menu item to set up intermediate difficulty level */
	private JMenuItemIntermediate menuItemIntermediate;

	/** The menu item to set up advanced difficulty level */
	private JMenuItemAdvanced menuItemAdvanced;

	/** The menu item for game players highest score*/
	private JMenuItemHighScore menuItemHighScore;

	/** The menu item for game developers information */
	private JMenuItemAbout menuItemAbout;

	/**
	 * Method responsible for set up
	 * beginner level options on the
	 * game canvas control.
	 * 
	 */
	public void setUpBeginnerOptions(){
		if(this.menuItemBeginner.isSelected()) {
			this.canvas.setNumberOfAliens(Constants.BEGGINER[0]);
			this.canvas.setNumberOfAlienShips(Constants.BEGGINER[1]);
			this.canvas.setScorePerLive(Constants.BEGGINER[2]);
			this.canvas.setMotherShipHits(Constants.BEGGINER[3]);
			this.canvas.setAlienShipHits(Constants.BEGGINER[4]);
			this.canvas.startGame();
			this.canvas.requestFocus();
			this.disableMenuLevels();
			
		}
	}

	/**
	 * Method responsible for set up
	 * intemerdiate level options on the
	 * game canvas control. 
	 * 
	 */
	public void setUpIntermediateOptions() {
		if(this.menuItemIntermediate.isSelected()) {
			this.canvas.setNumberOfAliens(Constants.INTERMEDIATE[0]);
			this.canvas.setNumberOfAlienShips(Constants.INTERMEDIATE[1]);
			this.canvas.setScorePerLive(Constants.INTERMEDIATE[2]);
			this.canvas.setMotherShipHits(Constants.INTERMEDIATE[3]);
			this.canvas.setAlienShipHits(Constants.INTERMEDIATE[4]);
			this.canvas.startGame();
			this.canvas.requestFocus();
			this.disableMenuLevels();
		}
	}

	/**
	 * Method responsible for set up
	 * advanced level options on the
	 * game canvas control.
	 * 
	 */
	public void setUpAdvancedOptions() {
		if(this.menuItemAdvanced.isSelected()) {
			this.canvas.setNumberOfAliens(Constants.ADVANCED[0]);
			this.canvas.setNumberOfAlienShips(Constants.ADVANCED[1]);
			this.canvas.setScorePerLive(Constants.ADVANCED[2]);
			this.canvas.setMotherShipHits(Constants.ADVANCED[3]);
			this.canvas.setAlienShipHits(Constants.ADVANCED[4]);
			this.canvas.startGame();
			this.canvas.requestFocus();
			this.disableMenuLevels();
		}
	}

	/**
	 * Method responsible for setup
	 * sound effects volume control.
	 * 
	 */
	public void setUpSoundEffectVolume() {
		if(SoundEffect.getVolume() != Volume.MUTE) {
			SoundEffect.volume = SoundEffect.Volume.MUTE;
			this.menuItemVolume.setText("Un-mute sounds");
		} else {
			SoundEffect.volume = SoundEffect.Volume.LOW;
		}
		this.canvas.requestFocus();
	}

	/**
	 * Method responsible to read
	 * and show the 5th highest scores
	 * of the game.
	 * 
	 */
	public void highestScores() {

		// Local variables
		HighestScoreFile file = null;
		List<Integer> highScores = null;
		String scores = "";

		try {

			// Open file
			file = new HighestScoreFile("projetofinal/scores.dat");

			// Retrieve file data
			highScores = file.getHighestScores();

			// Mount view information
			for(int i = 0; i < highScores.size(); i++) {
				scores += i + 1 + "st. ";
				scores += highScores.get(i);
				scores += "\n";
			}

			Messages.showPlainMessage(this, scores);

		} catch(IllegalArgumentException e) {
			e.printStackTrace();
			Messages.showFailure(this, "Failed to open scores file!");
		} catch(IOException e) {
			e.printStackTrace();
			Messages.showFailure(this, "Failed to read scores file!");
		} finally {
			this.canvas.requestFocus();
		}
	}

	/**
	 * Method responsible for show
	 * the project collaborators to
	 * the user.
	 * 
	 */
	public void about() {
		Messages.showPlainMessage(
				this,
				"Universidade Federal de Itajuba\n" + 
				"CCT 720 - Computacao Grafica II \n" +
				"Professor: Dr. Edison Oliveira de Jesus\n" +
				"Aluno: Felipe Agostini Knappe - 12623"
		);
		this.canvas.requestFocus();
	}
	
	/**
	 * Method responsible for disable
	 * level menu options.
	 * 
	 */
	private void disableMenuLevels() {
		this.menuItemBeginner.setEnabled(false);
		this.menuItemIntermediate.setEnabled(false);
		this.menuItemAdvanced.setEnabled(false);
	}
}
